/*
 * date: 2009-11-20 
 * author: Maciej Smolenski <jezdnia@gmail.com>
 */
#ifndef _RPC_CONFIG_HPP_
#define _RPC_CONFIG_HPP_

#include "rpc_config_data.hpp"
#include "ctor_helper.hpp"
#include "rpc_share.hpp"
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>

using namespace rpc_monitor;

namespace rpc_config
{

namespace bi=boost::interprocess;

template <typename CT>
class rpc_config_service : rpc_share<CT>
{
	ctor_helper<rpcm_config *, CT> m_config;
public:
	rpc_config_service(const char * p_memory_name, const int p_memory_size, const char *p_mutex_name);
	rpc_config_service(const char * p_memory_name, const char *p_mutex_name);
	~rpc_config_service();

	result_t get_hosts(stdset &so);
	result_t set_hosts(stdset &si);
	result_t add_host(rpc_host_entry_string &he);
	result_t del_host(rpc_host_entry_string &he);
	result_t get_delay(long &p_delay);
	result_t set_delay(long &p_delay);
	result_t get_ping_timeout(long &p_ping_timeout);
	result_t set_ping_timeout(long &p_ping_timeout);
	result_t get_portmap_timeout(long &p_portmap_timeout);
	result_t set_portmap_timeout(long &p_portmap_timeout);
	result_t get_pgroup(int &p_portmap_timeout);
	result_t set_pgroup(int &p_portmap_timeout);
private:
	template <typename FT>
	result_t get_field(FT rpcm_config::* field, FT &value);
	template <typename FT>
	result_t set_field(FT rpcm_config::* field, FT &value);
};

template <typename CT>
rpc_config_service<CT>::rpc_config_service(const char *p_memory_name, const int p_memory_size, const char *p_mutex_name) : rpc_share<CT>(p_memory_name, p_memory_size, p_mutex_name), m_config(rpc_share<CT>::m_memory.m_t) {
	m_config.m_t->init(rpc_share<CT>::m_memory.m_t);
};

template <typename CT>
rpc_config_service<CT>::rpc_config_service(const char *p_memory_name, const char *p_mutex_name) : rpc_share<CT>(p_memory_name, p_mutex_name), m_config(rpc_share<CT>::m_memory.m_t) {
};

template <typename CT>
rpc_config_service<CT>::~rpc_config_service(){
};

template <>
rpc_config_service<bi::create_only_t>::~rpc_config_service(){
	m_config.m_t->deinit(rpc_share<bi::create_only_t>::m_memory.m_t);
};

template <typename CT>
result_t rpc_config_service<CT>::get_hosts(stdset &so)
{
	bi::managed_shared_memory &segment = rpc_share<CT>::m_memory.m_t;
	rpcm_config &rpc = *m_config.m_t;
	bi::scoped_lock<bi::named_mutex> mutex(rpc_share<CT>::m_mutex.m_t);
	bi_set_to_std_set(segment, *rpc.m_hosts, so);
	return result_success;
}

template <typename CT>
result_t rpc_config_service<CT>::set_hosts(stdset &si)
{
	bi::managed_shared_memory &segment = rpc_share<CT>::m_memory.m_t;
	rpcm_config &rpc = *m_config.m_t;
	bi::scoped_lock<bi::named_mutex> mutex(rpc_share<CT>::m_mutex.m_t);
	std_set_to_bi_set(segment, si, *rpc.m_hosts);
	return result_success;
}

template <typename CT>
result_t rpc_config_service<CT>::add_host(rpc_host_entry_string &he)
{
	bi::managed_shared_memory &segment = rpc_share<CT>::m_memory.m_t;
	rpcm_config &rpc = *m_config.m_t;
	bi::scoped_lock<bi::named_mutex> mutex(rpc_share<CT>::m_mutex.m_t);
	shm_char_allocator ca(segment.get_segment_manager());
	rpc_host_entry_shm_string hes(he, ca);
	rpc.m_hosts->insert(hes);
	return result_success;
}

template <typename CT>
result_t rpc_config_service<CT>::del_host(rpc_host_entry_string &he)
{
	bi::managed_shared_memory &segment = rpc_share<CT>::m_memory.m_t;
	rpcm_config &rpc = *m_config.m_t;
	bi::scoped_lock<bi::named_mutex> mutex(rpc_share<CT>::m_mutex.m_t);
	shm_char_allocator ca(segment.get_segment_manager());
	rpc_host_entry_shm_string hes(he, ca);
	rpc.m_hosts->erase(hes);
	return result_success;
}




template <typename CT>
template <typename FT>
result_t rpc_config_service<CT>::get_field(FT rpcm_config::* field, FT &value)
{
	bi::managed_shared_memory &segment = rpc_share<CT>::m_memory.m_t;
	rpcm_config &rpc = *m_config.m_t;
	bi::scoped_lock<bi::named_mutex> mutex(rpc_share<CT>::m_mutex.m_t);
	value = rpc.*field;
	return result_success;
}


template <typename CT>
template <typename FT>
result_t rpc_config_service<CT>::set_field(FT rpcm_config::* field, FT &value)
{
	bi::managed_shared_memory &segment = rpc_share<CT>::m_memory.m_t;
	rpcm_config &rpc = *m_config.m_t;
	bi::scoped_lock<bi::named_mutex> mutex(rpc_share<CT>::m_mutex.m_t);
	rpc.*field = value;
	return result_success;
}


template <typename CT>
result_t rpc_config_service<CT>::get_delay(long &p_delay)
{
	return get_field<long>(&rpcm_config::m_delay, p_delay);
}


template <typename CT>
result_t rpc_config_service<CT>::set_delay(long &p_delay)
{
	return set_field<long>(&rpcm_config::m_delay, p_delay);
}

template <typename CT>
result_t rpc_config_service<CT>::get_ping_timeout(long &p_ping_timeout)
{
	return get_field<long>(&rpcm_config::m_ping_timeout, p_ping_timeout);
}


template <typename CT>
result_t rpc_config_service<CT>::set_ping_timeout(long &p_ping_timeout)
{
	return set_field<long>(&rpcm_config::m_ping_timeout, p_ping_timeout);
}

template <typename CT>
result_t rpc_config_service<CT>::get_portmap_timeout(long &p_portmap_timeout)
{
	return get_field<long>(&rpcm_config::m_portmap_timeout, p_portmap_timeout);
}


template <typename CT>
result_t rpc_config_service<CT>::set_portmap_timeout(long &p_portmap_timeout)
{
	return set_field<long>(&rpcm_config::m_portmap_timeout, p_portmap_timeout);
}

template <typename CT>
result_t rpc_config_service<CT>::get_pgroup(int &p_pgroup)
{
	return get_field<int>(&rpcm_config::m_pgroup, p_pgroup);
}


template <typename CT>
result_t rpc_config_service<CT>::set_pgroup(int &p_pgroup)
{
	return set_field<int>(&rpcm_config::m_pgroup, p_pgroup);
}


}

#endif

